{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>exam1</th>\n",
       "      <th>exam2</th>\n",
       "      <th>admitted</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>34.623660</td>\n",
       "      <td>78.024693</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>30.286711</td>\n",
       "      <td>43.894998</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>35.847409</td>\n",
       "      <td>72.902198</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>60.182599</td>\n",
       "      <td>86.308552</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>79.032736</td>\n",
       "      <td>75.344376</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       exam1      exam2  admitted\n",
       "0  34.623660  78.024693         0\n",
       "1  30.286711  43.894998         0\n",
       "2  35.847409  72.902198         0\n",
       "3  60.182599  86.308552         1\n",
       "4  79.032736  75.344376         1"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_csv('ex2data1.txt', names=['exam1', 'exam2', 'admitted'])\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>exam1</th>\n",
       "      <th>exam2</th>\n",
       "      <th>admitted</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>100.000000</td>\n",
       "      <td>100.000000</td>\n",
       "      <td>100.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>65.644274</td>\n",
       "      <td>66.221998</td>\n",
       "      <td>0.600000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>19.458222</td>\n",
       "      <td>18.582783</td>\n",
       "      <td>0.492366</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>30.058822</td>\n",
       "      <td>30.603263</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>50.919511</td>\n",
       "      <td>48.179205</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>67.032988</td>\n",
       "      <td>67.682381</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>80.212529</td>\n",
       "      <td>79.360605</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>99.827858</td>\n",
       "      <td>98.869436</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            exam1       exam2    admitted\n",
       "count  100.000000  100.000000  100.000000\n",
       "mean    65.644274   66.221998    0.600000\n",
       "std     19.458222   18.582783    0.492366\n",
       "min     30.058822   30.603263    0.000000\n",
       "25%     50.919511   48.179205    0.000000\n",
       "50%     67.032988   67.682381    1.000000\n",
       "75%     80.212529   79.360605    1.000000\n",
       "max     99.827858   98.869436    1.000000"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "创建两个分数的散点图，并使用颜色编码来可视化，如果样本是正的（被接纳）或负的（未被接纳）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEpCAYAAAB8/T7dAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deZRU9Znw8e/TII0oCq1sAdky7KAohIgmYFwyMRpFjNGokTjBheiAkjHBo3HeLPoySSZG57zEhQQRHVywUQ9EE4ILJpKlEVGQzQUUZOmwKaAQup73j3tvdXVR1V3b3aqezzl1quvW9uuq7vv81ucnqooxxhgDUBV2AYwxxkSHBQVjjDFJFhSMMcYkWVAwxhiTZEHBGGNMUuuwC2D8s2zZss6tW7eeCQzFKgCmsiWAlYcOHZo4YsSI7WEXJsosKJSx1q1bz+zateugTp067aqqqrK5x6ZiJRIJqa+vH7x169aZwAVhlyfKrPZY3oZ26tTpIwsIptJVVVVpp06d9uC0mk0zLCiUtyoLCMY43P8FO+e1wD4gY4wxSRYUjO8efvjhDiIyYvny5W0z3T9q1KgBS5YsaZfr6y1ZsqTdt7/97RMAFixY0H7RokVHeffNmTOnw7JlyzK+T3PatWt3cr7PiTIRGXHNNdf08G7fcccdXaZOnfqZ5p6Ty2c3YMCAwV/72tf6ZLt/wYIF7b/0pS/9Sz5lvfTSS3t57ztt2rSu3vF//OMfraZPn94pn9cCmDp16mfuuOOOLvk+zzgsKBjfPfbYYzWnnHLK3jlz5tSU4vXGjBmz/6GHHvoA4IUXXmj/yiuvHO3d9/TTT3d44403jizF+/gukYCHH+5AIpHb8Ty0adNGf/e733XcsmVLzpNJWvrsXnvttbaqyl//+tf2H330UcnOHY8//vjGESNGfApw7733dvOO79ixo9VvfvObzqV6H5MbCwomafPm+2peffUzw156qWrEq69+ZtjmzfcVfRLfs2dPVV1d3dGzZs3aMH/+/I4Ae/fulfPPP79v//79B5933nl9P/30U/Ee365du5MnTZrUfciQIYNOO+20/i+++GK7UaNGDejRo8ewRx999FhorI2uXbu2zcMPP9zpvvvu6zJw4MDBCxcuPPqPf/xjh9tvv73HwIEDB69atap61apV1V/84hf7DRkyZNCIESMGeK2VNWvWtBk+fPjAoUOHDpoyZUqzNWjfPPJIByZM+CwTJ56QDACJBEyceAITJnyWRx7pUOhLt2rVSq+66qr6u+6667Aa87p169qMHj26f//+/QePHj26//r169ssWrToqPTPLv15s2fPrvnGN76xY8yYMR/NnTs3WbZ58+Yd06dPnyEjRowYMG/evOTxqVOnfmb8+PG9Tz/99H7du3cfNnv27A7XX399j/79+w/+4he/2O/AgQMCjS3F7373u90PHDhQNXDgwMEXXHBBn+9973s9Pvjgg+qBAwcOvu6663oA/PCHP+wydOjQQf379x988803J7+3H/zgB1179+499LTTTuu/fv36w8pucmdBwQBOQHjnnZt7HTy4pQ0oBw9uafPOOzf3KjYwPProox3OOOOMPSeeeOKBDh06NPzpT39q94tf/KLzkUcemVi3bt1bd9xxx5a33nor2f3zySefVH3pS1/6eNWqVauPOuqohttvv737K6+8su7JJ598+yc/+Un31NceMGDAwauuuqr++uuv37ZmzZq3zjvvvL1nn3327p/+9Keb1qxZ89aQIUMOTJw4sdeMGTPeX7Vq1eqf//znmyZNmtQT4Lvf/W7PiRMn1q9cuXJ1165d/1nM71iwK6/czdVXb2fWrM7JwDBx4gnMmtWZq6/ezpVX7i7m5W+55ZbttbW1NTt27GiVevz666/vefnll+9Yt27dW5deeumOSZMmnXDOOefsS//s0l/vmWeeqbnqqqt2XX755Tsff/zxGoD9+/fLjTfe2PvZZ599++9///va7du3H5H6nI0bN1a/8MILb8+bN+/t66+/vs+ZZ5750bp1695q27Zt4oknnjg29bEzZszYXF1dnVizZs1bzz777Hv//d//vemEE044sGbNmrfuv//+TbW1tce8/fbbbd94443Vq1evfuv1119v99xzzx39yiuvtJs/f37Nm2+++daCBQveXrFixVGYgtk6BQPAxo0/7p5IfNqkkpBIfFq1ceOPu3fvfv3OQl/3iSeeqJkyZcp2gIsvvnjnnDlzat55553qyZMnbwf4/Oc//0n//v33e48/4ogj9Otf//pHAEOGDPmkuro6UV1draNGjfpk8+bNbfJ57z179lQtX7786EsuueSz3rGDBw8KwGuvvXb0c8899w7Addddt+MnP/lJj2yv45uqKpg58wMAZs3qzKxZTlfJ1VdvZ+bMD6gqrs5WU1OTuOSSS3ZMnz6985FHHpnsi1q+fPlR3u8+adKknT/60Y9a/N1ffvnldjU1NYf69+9/sG/fvgcnTZrUu76+vtX69evb9OjR48CwYcMOAFxxxRU7Zs6cmRwHOPvss/d4319DQ4OkfrfvvfdeXt/n888/f8ySJUuOGTx48GCA/fv3V61Zs6btxx9/XPXVr351d/v27RMAX/7yl4sKppXOgoIB4ODBrRn/QbMdz8XWrVtb/eUvfzlm3bp1R9544400NDSIiOjgwYP3i0jG57Ru3Vqr3JNhVVUV1dXVCtCqVSsaGhoyPymLhoYG2rdvf2jNmjVvZbo/EtN1vcDgBQSgFAHBc+utt2475ZRTBl922WX/KOZ15syZU/Puu++27d69+zCAffv2tZozZ07HU089dV+27xJo8v2lf7eHDh3K6/tUVW666aYtt9xyS5Pf5cc//nHn5spg8mPdRwaANm26HszneC7mzJnTcfz48Ts+/PDDNzdv3vzm1q1b3+jRo8fB4cOH73/kkUdqAP7+97+3XbduXc4zj9K1b9++4eOPP052jxx99NEN3iBoTU1NokePHgd/+9vfdgRIJBIsXbr0SIBTTjll74MPPlgD8OCDDx5X6PsXzesySpU6xlCkLl26NHzta1/b9b//+7/He8dOPvnkfTNnzuwIcP/999eMHDlyLzT97FI1NDSwYMGCmuXLl6/avHnzm5s3b35z7ty5bz/55JM1w4cP/3TTpk1tvDGIxx57rKjuxtatW6s31nDsscc27Nu3L1mec88996M5c+Ycv2fPniqA995774jNmze3PvPMM/cuXLiww969e2XXrl1VixYtKngsxlhQMK5eve7YXFXVtsmZqKqqbaJXrzs2F/qaTz755HHjx4/flXrswgsv3LVx48bqffv2terfv//gu+66q+uwYcP2FfoeF1988e6FCxd2GDhw4ODnn3/+6CuuuGLnvffe23XQoEGDV61aVT137tx3Z82adfyAAQMG9+vXb8hTTz3VAWDGjBnvP/DAA52HDh06aM+ePa1aeh9fpI8hNDQsO2yMoQRuu+22rbt37072Cvz6179+f86cOcf3799/8Ny5c4+bMWPGBwDpn533+Oeee659ly5dDvbp0yc59nLuued+/Pbbb7etr69v/T//8z8b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\n",
      "text/plain": [
       "<Figure size 432x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "positive = data[data.admitted.isin(['1'])]  # 1\n",
    "negetive = data[data.admitted.isin(['0'])]  # 0\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(6,5))\n",
    "ax.scatter(positive['exam1'], positive['exam2'], c='y', label='Admitted')\n",
    "ax.scatter(negetive['exam1'], negetive['exam2'], s=50, c='r', marker='x', label='Not Admitted')\n",
    "# 设置图例显示在图的上方\n",
    "box = ax.get_position()\n",
    "ax.set_position([box.x0, box.y0, box.width , box.height* 0.8])\n",
    "ax.legend(loc='center left', bbox_to_anchor=(0.2, 1.12),ncol=3)\n",
    "# 设置横纵坐标名\n",
    "ax.set_xlabel('Exam 1 Score')\n",
    "ax.set_ylabel('Exam 2 Score')\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sigmoid function\n",
    "首先来回顾下 logistic回归的假设函数：\\\\[{{h}_{\\theta }}\\left( x \\right)={g({\\theta}^T X)}=\\frac{1}{1+{{e}^{-{{\\theta }^{T}}X}}}\\\\] \n",
    "其中的 g代表一个常用的logistic function为S形函数（Sigmoid function）：\n",
    "$$g\\left( z \\right)=\\frac{1}{1+{{e}^{-z}}}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(z):\n",
    "    return 1 / (1 + np.exp(- z))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "做一个快速的检查，来确保它可以工作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x1 = np.arange(-10, 10, 0.1)\n",
    "plt.plot(x1, sigmoid(x1), c='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cost function\n",
    "逻辑回归的代价函数如下:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cost(theta, X, y):\n",
    "    first = (-y) * np.log(sigmoid(X @ theta))\n",
    "    second = (1 - y)*np.log(1 - sigmoid(X @ theta))\n",
    "    return np.mean(first - second)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 获取训练集数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# add a ones column - this makes the matrix multiplication work out easier\n",
    "if 'Ones' not in data.columns:\n",
    "    data.insert(0, 'Ones', 1)\n",
    "\n",
    "# set X (training data) and y (target variable)\n",
    "X = data.iloc[:, :-1].values  # Convert the frame to its Numpy-array representation.\n",
    "y = data.iloc[:, -1].values # Return is NOT a Numpy-matrix, rather, a Numpy-array.\n",
    "\n",
    "theta = np.zeros(X.shape[1])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "检查矩阵的维度，确保一切良好。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((100, 3), (3,), (100,))"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape, theta.shape, y.shape\n",
    "# ((100, 3), (3,), (100,))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6931471805599453"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cost(theta, X, y)\n",
    "# 0.6931471805599453"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# gradient descent(梯度下降)\n",
    "* 这是批量梯度下降（batch gradient descent）  \n",
    "* 转化为向量化计算： $\\frac{1}{m} X^T( Sigmoid(X\\theta) - y )$\n",
    "$$\\frac{\\partial J\\left( \\theta  \\right)}{\\partial {{\\theta }_{j}}}=\\frac{1}{m}\\sum\\limits_{i=1}^{m}{({{h}_{\\theta }}\\left( {{x}^{(i)}} \\right)-{{y}^{(i)}})x_{_{j}}^{(i)}}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradient(theta, X, y):\n",
    "    return (X.T @ (sigmoid(X @ theta) - y))/len(X)  \n",
    "# the gradient of the cost is a vector of the same length as θ where the jth element (for j = 0, 1, . . . , n)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ -0.1       , -12.00921659, -11.26284221])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gradient(theta, X, y)\n",
    "# array([ -0.1, -12.00921659, -11.26284221])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Learning θ parameters\n",
    "注:实际上没有在这个函数中执行梯度下降，仅仅是在计算梯度。在练习中，一个称为“fminunc”的Octave函数是用来优化函数来计算成本和梯度参数。由于我们使用Python，我们可以用SciPy的“optimize”命名空间来做同样的事情。\n",
    "\n",
    "这里我们使用的是高级优化算法，运行速度通常远远超过梯度下降。方便快捷。\n",
    "只需传入cost函数，已经所求的变量theta，和梯度。cost函数定义变量时变量tehta要放在第一个，若cost函数只返回cost，则设置fprime=gradient。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy.optimize as opt\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里使用fimin_tnc或者minimize方法来拟合，minimize中method可以选择不同的算法来计算，其中包括TNC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([-25.16131853,   0.20623159,   0.20147149]), 36, 0)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result = opt.fmin_tnc(func=cost, x0=theta, fprime=gradient, args=(X, y))\n",
    "result\n",
    "\n",
    "# (array([-25.16131867,   0.20623159,   0.20147149]), 36, 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面是第二种方法，结果是一样的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "     fun: 0.203497701589475\n",
       "     jac: array([9.14875519e-09, 9.99037356e-08, 4.79345707e-07])\n",
       " message: 'Local minimum reached (|pg| ~= 0)'\n",
       "    nfev: 36\n",
       "     nit: 17\n",
       "  status: 0\n",
       " success: True\n",
       "       x: array([-25.16131853,   0.20623159,   0.20147149])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = opt.minimize(fun=cost, x0=theta, args=(X, y), method='TNC', jac=gradient)\n",
    "res\n",
    "# help(opt.minimize) \n",
    "# res.x  # final_theta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.203497701589475"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cost(result[0], X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 验证逻辑回归\n",
    "学习好了参数θ后，用这个模型预测某个学生是否能被录取。\n",
    "\n",
    "接下来，需要编写一个函数，用所学的参数theta来为数据集X输出预测。然后就可以使用这个函数来给分类器的训练精度打分。\n",
    "\n",
    "逻辑回归模型的假设函数：$$ {{h}_{\\theta }}\\left( x \\right)=\\frac{1}{1+{{e}^{-{{\\theta }^{T}}X}}}$$\n",
    "当$h_{\\theta}(x)$ 大于等于0.5时，预测 y=1;当$h_{\\theta}(x)$ 小于0.5时，预测 y=0 。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(theta, X):\n",
    "    probability = sigmoid(X@theta)\n",
    "    return [1 if x >= 0.5 else 0 for x in probability]  # return a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.89"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_theta = result[0]\n",
    "predictions = predict(final_theta, X)\n",
    "correct = [1 if a==b else 0 for (a, b) in zip(predictions, y)]\n",
    "accuracy = sum(correct) / len(X)\n",
    "accuracy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可以用skearn中的方法来检验。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.85      0.87      0.86        39\n",
      "           1       0.92      0.90      0.91        61\n",
      "\n",
      "    accuracy                           0.89       100\n",
      "   macro avg       0.88      0.89      0.88       100\n",
      "weighted avg       0.89      0.89      0.89       100\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(predictions, y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 决策边界\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "x1 = np.arange(130, step=0.1)\n",
    "x2 = -(final_theta[0] + x1*final_theta[1]) / final_theta[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfQAAAFNCAYAAAD2E503AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3dd3xUVfrH8c+TAKGDVJESikgRbICKCkERGyrFtetaFzt1d637W3cVXVcBwc7aFdvSBQvISqiioChdeic06T05vz9mIpMwaWRm7pTv+/XKK5k7k3ufuYF57j3nOeeYcw4RERGJbUleByAiIiLFp4QuIiISB5TQRURE4oASuoiISBxQQhcREYkDSugiIiJxQAldJAaZ2ZdmdlshXrfHzBpGIiavmNkqM7vY6zhEvFbC6wBE4pWZrQJqAkeATGAh8D4w1DmXVZx9O+cuL+TryhfnOHkJeG+ZwGFgBnCvc25tOI4nIgXTHbpIeF3lnKsApAL/Ah4G3vI2pJC5yn/BUAvIAF7yOJ4iMTPd0EhcUUIXiQDn3E7n3FjgeuA2M2sBYGYpZvaCma0xswwze93MymT/npl1MbO5ZrbLzJab2WX+7ZPN7G7/zyebWbqZ7TSzrWb2acDvOzM72f9zJTN738y2mNlqM3vCzJL8z91uZtP8sfxmZivNrLCtAAeA4UDzgOPmd6wnzezDgNfW98dZIuC9PWVm081st5lNMLNqAa+/1b/PbWb2eGAsZna2mc00sx1mttHMXjazUrnOxwNmthRYamavmNmAXPv43Mx6F+a9i0QTJXSRCHLOfQ+sA9r5Nz0HnAKcAZwM1Ab+D3zJCV8T/V+AykB7YFWQ3T4FTABOAOqQ953yS0AloCGQBvwRuCPg+XOAJUA14N/AW2ZmBb0nMyuL70LluyIcqyA3+V9fAygF/Nl/rObAa8CtwElAVXzvOVsm0Mf/HtoCHYH7c+27K7732hx4D7gx4GKjmv93Pi5CrCJRQQldJPI2AFX8yfJPQB/n3Hbn3G7gGeAG/+vuAt52zk10zmU559Y75xYH2d9hfE36JznnDjjnpuV+gZkl40u6jzrndjvnVgED8CXGbKudc/9xzmXiS3S18PWT52W0me0AdgGdgOeLcKyCvOOc+9U5tx/4DN8FD8AfgHHOuSnOuYPA34Df6xGcc3Occ9855474j/sGvguKQM/6z/d+/wXWTnxJHHznfrJzLqMIsYpEBSV0kcirDWwHqgNlgTn+JuIdwFf+7QB1geWF2N9fAQO+N7MFZnZnkNdUw3enuzpg22p/LNk2Zf/gnNvn/zG/orquzrnKQArwIJBuZicW8lgF2RTw876AOE4Cfi+8c87tBbZlPzazU8xsnJltMrNd+C6QqpFT7sK994Bb/D/fAnxQhDhFooYSukgEmVkbfIltGrAV2A+c6pyr7P+qFFCZvhZoVNA+nXObnHN/cs6dBNwDvJrdbx5gK0fv5LPVA9YX7x2Bcy7TOTcSX3P3BYU41l58FzLZTizC4Tbiu9ABfm/urxrw/GvAYqCxc64i8Bi+i50cIed6/CHQxcxOB5oBo4sQj0jUUEIXiQAzq2hmVwKfAB865+b5h679BxhkZjX8r6ttZpf6f+0t4A4z62hmSf7nmgbZ97Vmlt2P/Bu+hJUZ+Bp/M/pnQH8zq2BmqUBffMmsuO/NzKwLvj78RYU41lygvZnVM7NKwKNFONxw4Eozu8Bf7PZPcn6OVcDXBbDHf67uK2iHzrl1wA/47sxH+Jv5RWKOErpIeH1uZrvx3W0/DgwkZ3HYw8Ay4Dt/E/E3QBP4vYDuDmAQvn7edHLe9WZrA8wysz3AWKCXc25lkNc9hO/ueAW+FoKPgLeL+d724Eug/YHbnHMLCjqWc24i8CnwCzAHGFfYA/r3/4B/fxvxXcCsC3jJn/EV1O3Gd7H0ae595OE9oCVqbpcYZs7lbn0SEUksZtYeXwtC/eJO+iPiFd2hi0hCM7OSQC/gTSVziWVK6CKSsMysGbAD3xC9Fz0OR6RY1OQuIiISB3SHLiIiEgeU0EVEROJATK82VK1aNVe/fn2vwxAREYmYOXPmbHXOVc+9PaYTev369Zk9e7bXYYiIiESMma0Otl1N7iIiInFACV1ERCQOKKGLiIjEASV0ERGROKCELiIiEgeU0EVEROKAErqIiEgciOmEfihTCyOJiIhAjCf0XzN289rk5RxWYhcRkQQX0wm9QkpJnvtqMVe9NI05q3/zOhwRERHPxHRCT61alqG3tmLX/sNc89oMHhs1j537DnsdloiISMTFdEIHuOTUE5nYN427L2jAJ9+voePAyYyZux6t8y4iIokk5hM6QLmUEjxxZXPGPngBJ1UuQ69P5vLHt79n9ba9XocmIiISEXGR0LO1qF2JUfefzz+uPpWf1uzgkkFTeOXbZRw6oqI5ERGJb3GV0AGSk4zbzqvPN33T6NisBs9/vYTOQ6by/crtXocmIiISNmFL6Gb2tpltNrP5AdueN7PFZvaLmY0ys8oBzz1qZsvMbImZXVrc459YqTSv3tyKt29vzb5DmVz3xkweHv4LO/YdKu6uRUREok4479DfBS7LtW0i0MI5dxrwK/AogJk1B24ATvX/zqtmlhyKIC5qWpOJfdtzT/uGDP9xHR0HpDPqp3UqmhMRkbgStoTunJsCbM+1bYJz7oj/4XdAHf/PXYBPnHMHnXMrgWXA2aGKpWypEjx6RTM+f/AC6lYpS59Pf+aWt2axYsueUB1CRETEU172od8JfOn/uTawNuC5df5tIdX8pIqMvO88nu7agl/W7eSywVMZ/M1SDh7JDPWhREREIsqThG5mjwNHgGHZm4K8LGibuJn1MLPZZjZ7y5YtRT52UpJxy7mpTOqbxiXNazLom1+5fPBUZi7fVuR9iYiIRIuIJ3Qzuw24ErjZHe3IXgfUDXhZHWBDsN93zg11zrV2zrWuXr36ccdRo2JpXr7pLN69ow2HM7O48T/f8ef//sz2vSqaExGR2BPRhG5mlwEPA1c75/YFPDUWuMHMUsysAdAY+D4SMXVoUoMJvdO4v0MjRv+0no4DJvPf2WtVNCciIjElnMPWPgZmAk3MbJ2Z3QW8DFQAJprZXDN7HcA5twD4DFgIfAU84JyLWMd2mVLJ/PWypozv2Y5G1cvzl+G/cMPQ71i2WUVzIiISGyyW70Rbt27tZs+eHdJ9ZmU5Pp29lme/WMT+w5ncl9aI+y88mdIlQzKKTkREpFjMbI5zrnXu7XE3U1xxJSUZN55dj0n9OtC5ZS2G/G8Zlw+eyvRlW70OTUREJE9K6HmoXiGFF284kw/uOhvnHDe/OYs+n85l656DXocmIiJyDCX0ArRrXJ2verfnoYtOZtwvG+g4IJ1Pvl9DVlbsdlWIiEj8UUIvhNIlk+l3SRO+7NWOJjUr8MjIeVw/dCa/Zuz2OjQRERFACb1ITq5RgU96nMu/rzmNpZv3cMXgqTz/9WIOHNZMcyIi4i0l9CJKSjKua1OXSX3T6HJGbV75djmXDJrClF+LPmudiIhIqCihH6eq5VMYcN3pfPSncyiRZPzx7e/p+fFPbN59wOvQREQkASmhF9N5jarxZe929L64MV/N30THAel8+N1qFc2JiEhEKaGHQEqJZHpffApf9m5Hi5Mq8cTo+fzh9Rks3rTL69BERCRBKKGHUKPq5fnoT+cw4NrTWbVtH1cOmcazXy5i36EjBf+yiIhIMSihh5iZcU2rOkzqm0b3s2rzRvoKLhk0hW8Xb/Y6NBERiWNK6GFyQrlS/PsPp/Npj3NJKZHEHe/+wAPDfiRjl4rmREQk9JTQw+ychlX5olc7+nU6hYmLMrh4QDrvz1xFpormREQkhJTQIyClRDIPdWzMhN7tOb1uZf5vzAK6vzaDBRt2eh2aiIjECSX0CKpfrRwf3HU2g284g/W/7ePql6fTf/xC9h5U0ZyIiBSPEnqEmRldzqjNpL4duK51Xf4zdSWdBqbzzcIMr0MTEZEYpoTukUplS/Js95YMv7ct5UuX4O73Z3PPB7PZuHO/16GJiEgMUkL3WOv6VRj3UDv+elkT0n/dwsUD0nln+koVzYmISJEooUeBUiWSuL/DyUzonUbr+lX4x+cL6frKdOatU9GciIgUjhJ6FKlXtSzv3tGGl286k027DtDllWn84/MF7FHRnIiIFEAJPcqYGVeedhLf9E3jpnPq8e6MVVw8IJ2vF2zyOjQREYliSuhRqlKZkjzdtSUj7juPymVLcs8Hc7j7vdms36GiOREROZYSepQ7q94JfP7QBTx2RVOmL9tKp4HpvDl1BUcys7wOTUREoogSegwomZxEj/aNmNi3Pec2rMrT4xdx9cvTmbt2h9ehiYhIlFBCjyF1TijLW7e15rWbz2Lb3oN0e3U6fx8zn10HDnsdmoiIeEwJPcaYGZe3rMU3fdO4rW193v9uNRcPSOeLeRtxTmPXRUQSlRJ6jKpQuiRPXn0qo+8/n+oVUrh/2I/c+e4PrN2+z+vQRETEA0roMe70upUZ88D5PNG5GbNWbqfToHReT1/OYRXNiYgkFCX0OFAiOYm72zVkYt802jWuzr++XMxVL01jzurfvA5NREQiRAk9jtSuXIb//LE1b9zaip37D/OH12fw+Kh57NyvojkRkXinhB6HLj31RCb2TePO8xvw8fdr6DggnbE/b1DRnIhIHFNCj1PlU0rwtyubM/bBC6hVqTQ9P/6JP779Pau37fU6NBERCQMl9DjXonYlRj9wPk9e1Zyf1uzgkkFTeOXbZRw6oqI5EZF4EraEbmZvm9lmM5sfsK2KmU00s6X+7ycEPPeomS0zsyVmdmm44kpEyUnG7ec34Ju+aVzUtAbPf72EK1+ayg+rtnsdmoiIhEg479DfBS7Lte0RYJJzrjEwyf8YM2sO3ACc6v+dV80sOYyxJaQTK5XmtVta8dZtrdl7MJNrX5/JIyN+Yce+Q16HJiIixRS2hO6cmwLkvgXsArzn//k9oGvA9k+ccwedcyuBZcDZ4Yot0XVsVpOJfdvTo31D/jtnHR0HpDPqp3XeFM05B6NG+b4XZruIiAQV6T70ms65jQD+7zX822sDawNet86/TcKkbKkSPHZFMz5/8ALqVilLn09/5pa3ZrFya4SL5kaPhu7doU+fo8nbOd/j7t19z4uISIGipSjOgmwLemtmZj3MbLaZzd6yZUuYw4p/zU+qyIj7zuOpLqfyy9qdXPriFIZMWsrBI5mRCaBrV+jVCwYPPprU+/TxPe7Vy/e8iIgUKNIJPcPMagH4v2/2b18H1A14XR1gQ7AdOOeGOudaO+daV69ePazBJorkJOPWtvWZ1C+NTs1rMnDir1wxeCrfrdgW/oObwaBBR5N6UtLRZD5okO95iRsZGcOYObM+kycnMXNmfTIyhnkdkkjciHRCHwvc5v/5NmBMwPYbzCzFzBoAjYHvIxxbwqtRsTSv3HQW79zRhoNHsrhh6Hf85b8/s31vmIvmspN6oBAlcyWQ6JGRMYwlS3pw8OBqwHHw4GqWLOmhv4lIiIRz2NrHwEygiZmtM7O7gH8BncxsKdDJ/xjn3ALgM2Ah8BXwgHMuQm2+ktuFTWowsU8a96Y1YtRP6+k4YDLD54SxaC67mT1QYJ/6cVICKbxIXPisWPE4WVk5VwPMytrHihWPh/xYIonIYnk60NatW7vZs2d7HUZcW7xpF4+Pms+c1b9xbsMq9O/WkkbVy4fuALn7zAcNOvbxcd6pz5xZ35/Mc0pJSaVt21XFDDz2ZWQMY8WKx/3nyAgsW0lKKkuTJkOpWfPmkB1v8uQkgpfGGB06hH+io6Pvdw0pKfVo2LB/SN+fSKSY2RznXOvc26OlKE6iVNMTK/Lfe9ryTLeWLNywi8tfnMqgib9y4PBxNKAEG4o2erQveXfuDAMHHtunXowq94MH1xRpeyLJ2XoBuRNtOO6cU1LqFXp7qFsM1FojiUAJXQqUlGTcdE49JvXrwOUtT2TwpKVcPngqM5ZtLdqOgg1R69LFl8zHj4cx/pKK7KQ+cmSxqtyLkkASTbDm79xCfeHTsGF/kpLK5tiWlFSWhg3759gWjuSr5n5JBEroUmjVK6Qw+IYzef/Os8lyjpvenEXfT+eybc/Bwu0g2BC1vn19yTz3EDUz6NatWIVxhU0giagwyTrUFz41a95MkyZDSUlJBYyUlNSgzfrhSL5qrZFEUMLrACT2tD+lOl/3bs/L/1vGG1OW878lm3n08qZc26ouSUn5JODAavbBg31fELYhatmJQv2mx0pJqRe0viBbuC58ata8ucDzH47km9f7VWuNxBMVxUmxLM3YzWOj5vHDqt84u34V+ndrQeOaFfL/Jed8482zZWVpvHmEZTdr57wT9hXGpaSkenrhE45ixmDvNxyFfyKRoKI4CYvGNSvwaY+2PHdNS5Zk7OaKIVN54esleRfNhWmImhRNsObvZs0+oEMHR9u2qzxNcuHoKilsc79ILNMduoTM1j0HeWb8Ikb+tJ7UqmV5umsL2jUOmM0vjEPUJL5oiJlI3vK6Q1dCl5CbsWwrj4+ez8qte+lyxkk80bk51Suk+Iasde+eM3kHJvmRI32FcJIwlLhFik4JXSLqwOFMXpu8nNcmL6d0ySQeubwZN7SuQ9LYMb5q9sA7ced8Q9pyb5e4Fi392rqokFijhC6eWLZ5D4+PmsesldtplXoC/bu1oOmJFb0OS6JANMzkFy0XFSJFoaI48cTJNcrzSY9zeeHa01mxZQ9XDpnGc18tZv8hTdWf6KJhbLgmnJF4ooQuYWdm/KFVHSb160C3M2vz2uTlXPJiOt8u2VzwL0vcioaZ/KLhokIkVJTQJWKqlCvF89eezic9zqVUchJ3vPMDD3z0I5t3HfA6NPFAqIanFWfe9+TkKkXaLhLNlNAl4s5tWJUverWjb6dTmLgwg44D0vlg5ioys2K3nkOKLhRjw4s773teNZiqzZRYpKI48dTKrXt5YvQ8pi/bxhl1K/NMt5Y0P0lFc6Dq6/zkXPr1WIUtrPN6SVeR46GiOIlKDaqV48O7zuHF689g7fZ9XPXyNJ75YhH7Dh3xOjRPabnPvB279OuxCtsHHg39+PkJ9TKyEt+U0MVzZkbXM2szqV8a17Wuw9ApK+g0cAqTFmV4HVqBwvWBq+rrvBVm6dfCJuRoXpFPF3VSVEroEjUqly3Fs91P47/3tqVsqWTuem829304h007o7NoLpwfuKq+zltB56AoCTma53jXRZ0UlZZPlajTpn4Vxvdsx3+mrmDIpKVMXbqVP19yCre2rU9yfsuzRlh+H7jFTQha7jNv+S/9mpwj6RXm71CYJV0jJbBuInjfvi7qJG+6Q5eoVKpEEg9ceDIT+rTnrNQTePLzhXR7dTrz1+8Myf5D0VQezrvoaG4K9lqwc2NWCigJ+CYsisXm6dwtPnkp7kWd+uXjlxK6RLXUquV47442DLnxTDbsOMDVL0/jn58vZM/B4y+aC1VTeTgLqsLVFBwPH+bBzk1SUgXgcI7XxVrzdGFqA4p7Uad++fimYWsSM3buP8y/v1rMsFlrqFWpNP+4+lQuOfXEIu8nVHOIx9o84LEWb2EUNHwtloaf5T2EDnwXLsUfuhgN8+dL8WnYmsS8SmVK0r9bS0bcdx6VypSkxwdz+NP7s9mwY3+R9hOqpvJoLqgKxosiq3C2CBRm+Fos1Rzk3eKTSocOWbRtu6rY/7ZUbBnfVBQnMadV6gl8/tAFvD1tJYO++ZWLB6bTt9Mp3H5efUokF3yNGsqCs2gqqCpIpD/Mc7cIZDfvQuGK1fLbb/535T6xVnPQsGH/oC0ooXwPKraMb7pDl5hUMjmJe9IaMbFPGuc0qMLT4xfR5ZXp/Lx2R4G/m6gFZ5GeRCUcLQKFuSsHor61JJhItPgk6r/9RKE+dIl5zjm+nL+JJ8cuYMueg9zWtj79LjmFCqVL5vk7iTitaqT70MMxrWpefcCB1B+cv0T8tx9v8upDV0KXuLHrwGEGfL2E979bTY0KKTx51alc1uJETCtt/C6SH+bhKMDKv3As9ov8RApDCV0Sxty1O3hs5DwWbtzFRU1r8I+rT6VulbIF/6KEVDhaBPK7Q09JSdXdpiQEVblLwjijbmXGPng+T3Ruxszl27hk0BTeSF/O4czYGL4UL8LRJ5xXH3CzZh+GpApcJJbpDl3i2vod+/n7mPl8s2gzTU+swDPdW3JWvRO8DkuKQX3AkujU5C4JyznH1wsyeHLsAjJ2H+Dmc+rxl0ubUqlM3kVzIiLRSk3ukrDMjMtanMg3/dK4/bz6fDRrDRcPTOfznzcQyxe0IiKBlNAlYZRPKcHfrzqVMQ9cQM2KKTz08U/c/s4PrNmW//zZEh9zwIvEO08Supn1MbMFZjbfzD42s9JmVsXMJprZUv93dXRKWLSsU4nR95/P/13ZnNmrttNpUDqvTl6mork8aEEPkdgQ8YRuZrWBnkBr51wLIBm4AXgEmOScawxM8j8WCYsSyUnceUEDvumXRocm1fn3V0u4csg05qze7nVoUceLOeBFpOi8anIvAZQxsxJAWWAD0AV4z//8e0BXj2KTeOYcjBrl+w7UqlSGN25tzZt/bMWe33ZxzWszeXTkPHbuO1zAjhKHFvQQiQ0RT+jOufXAC8AaYCOw0zk3AajpnNvof81GoEakY5MEMHo0dO8Offr8ntRxjouH/osJ/7qWP52YyWez19Jx4GTGzF2vojkiPwe8iBwfL5rcT8B3N94AOAkoZ2a3FOH3e5jZbDObvWXLlnCFKZGW6865wO3Hq2tX6NULBg8+mtT79IHBgyl3/z083usqxj54PrVPKEuvT+Zy61vfs2rr3tAcO0ZFckEPFd+JHD8vmtwvBlY657Y45w4DI4HzgAwzqwXg/7452C8754Y651o751pXr149YkFLmOVx50yfPr7to0eH5jhmMGjQ0aSelOT73quXb7sZp55UiZH3ncc/u5zKz2t3cMmLU3j5f0s5dCRxi+aSksr8/nNyctWwzJeu4juR4vEioa8BzjWzsuZbNaMjsAgYC9zmf81twBgPYhOv5HPnTK9evudDJTupB/In82zJScYf29bnm35pdGpWkxcm/MoVQ6Yya8W20MURA7KT7JEjR9+3c/vDciwV3xWdWjQkkBd96LOA4cCPwDx/DEOBfwGdzGwp0Mn/WBJFIe6cQyb7YiFQYMtAgJoVS/PKzWfxzu1t2H8ok+uHfsdfh//Mb3sPhS6eKBbJJKviu6JRi4bk5kmVu3Pu7865ps65Fs65W51zB51z25xzHZ1zjf3fNX4o0RTizjlfhemHz33nn5V1bMtAEBc2rcHEvu25J60hI35cT8eB6YyYsy7ui+YimWSjsfgumu+A1aIhuWmmOPFedsLNyjr2zvmqq3zbC6Mw/fCjRx975x/YMpBPX33ZUiV49PJmjHvoAlKrlqXff3/m5jdnsWLLnkKFF+nkEIrjRTLJRrL4rjCi/Q5YLRqSmxK6eC87EbdqdTTZZmbCGWfA+PFw9dWFq3IvTD98164wcmTOO//spD5yZKH66pvVqsiIe8+jf7cWzFu/k8tenMqL3/zKwSOZef5OpJNDqI4XySQbjuVWgynshU603wFHY4uGeEurrYn3nPPdiY8f70vic+ZA376+RHzGGTB3ri/ZdutWuH1lJ/Fs4eiH99u8+wBPj1vE2J830LBaOZ7u1oLzGlU75nUzZ9b3J9ecUlJSadt2VcjjCuXx4mm50uwLncBEnZRUNuiFw+TJSUCwz0ejQwfvRzwU5b1IfNHyqRLdsrJ8d+Ljxx/d1qsXDBwIY8b47pyL0peeFND4lJUVlmQeKP3XLfxt9HzWbN/HNWfV4fHOzahSrtTvz0c6OUR7MvJKUS50In0Rdjzi6WJLCk/Lp0p0S0qCzz/PuW3QIN/2bt2KlswLWcEeSmmnVGdCn/Y8cGEjxsxdz0UDJvPZ7LW/F81FunlUzbHB5d3vvPqY5vdo69MPpmbNm2nbdhUdOmTRtu0qJfMEp4Qu0SFYIg5WEJffzHHHWcEeKqVLJvOXS5vyRa92NK5Rnr8O/4Xrh37Hss27I54cYiEZeSG/C5rcdQaR6tMXCRUldPFesETcubOv+b1Vq6NJvaCZ44pRwR5Kp9SswKc92vLcNS1Zsmk3lw+eyoc/tya1UeSSQ37JKJqHYoVbsAudQLmL3nQHLLFEfejivVGjfEk6MBFnZfmS+dy5vuT++ec5k36wIjfnfEk7d397XtsjYOueg/Qfv4hRP62nftWyPN21JRc0PrZoLlKCFVKBAY6UlNSE6IM92u98bP+4T+LWGahPPjaoKE6iV14JN69CuTBVrIfTtKVbeWL0PFZt20fXM07iiSubU618SsTjyKvQK1siVUnHQtFbJKlqPnaoKE6il1nwwre8CuUKSuaRWrmtCC5oXI2verenZ8fGjJ+3kYtemMzH368hKyuysRQ06Ug0jbMON9UZ5BTt4+6lYEroEr2Ot2I9Uiu3FVHpksn07XQKX/ZqT9NaFXl05Dyue2MmSzbtjlgMhalyT5SZxlT0lpNmnot9SugSnYpTsR7JlduOw8k1yvNpj3N5/g+nsXzLHjoPmcq/v1rM/kN5zzQXKgUVhUF8DG0rbOGfit6O0lDH2Kc+dIlOwQrlAhNzQTPHRXjGuOO1fe8hnvliEcPnrKNulTI81aUFHZrUCOsxcxaF+QrissVDn6n6go+PzlvsUFGcxJZQVKx7MGPc8Zq5fBuPj57Hii17ufK0Wvzflc2pUbF02I8bWNVcokQVnIPMzO1RW+FcmCrsWCl2i8aK8miMSY6lhC6JJUbu0AM/QJNKNGTqtn/x3vflSCmZxF8va8rNZ9cjKSn88cbC3VlhY4yFaW9j4XxL9FKVuyQOj2eMK6zcK6JlHVlOuxNuY9itO2hZuxJ/Gz2fa16fwaKNu8IeSyxUOBc2xrz7fF3UTKTj5fkOVl+QyJMNxRMldIk/UTJjXEHy+lA/8tujDLv7HAZedzqrt+3jypem8ewXi9h36EjYYomFCufCxphf4V+0rGnu1fkOtqzuokV3sHjxnVG77rsUnhK6xJ8QrHkeCfl9qJsZ3ULD5JMAACAASURBVM+qw//6pXFtqzq8MWUFnQZO4X+LM8ISSyxUOBc2xpzD0Y4VDS0PXp3vYBeRcBjnDuXYEg3nSIpOCV3iT14T1eS13SOF+VCvXLYU/7rmND67py1lSiVz57uzuX/YHDJ2HQhpLLEwyUpRYswejuar4j+W1y0PXp3vorxvr8+RFJ0SukhuEZpprigf6mc3qMIXPdvxl0ubMGnRZjoOSOe9GavIDNFMc7EwycrxxBitLQ9ene+ivG+vz5EUnarcRXIr7hj4IjieYUKrt+3lidHzmbp0K6fXqUT/bi1pUbtSSOIprmgb9qRq8pyCL85TEjPL0eyeyOcoFmjYmkhh5a6SHzSo4JXeIh6iY+zPG3hq3CK27z3IHec3oG+nUyiXUsKzmKI1eUbbRUZukY4v2PGAqD5HktNxJXQzqwhUd84tz7X9NOfcL6EPs2iU0AUIz7KpMTKOfee+wzz39WI+mrWGkyqV5smrT+WSU0/0JJZYmdAlmoTqIijaL1oktIo8Dt3MrgMWAyPMbIGZtQl4+t3QhyhynMKxGEt2VXwgj5N5sLHClcqW5JluLRlxX1sqlC5Jjw/m0OP92WzYsT/i8cXC0LdoE4rx6MGGomnYWWLKryjuMaCVc+4M4A7gAzPr7n8uem5RRMKxGMvxrvQWJgV9aLdKrcK4nhfw8GVNmbJ0C50GpvPWtJUcyYzczGjRWoAWzUJxERQLkwJJZOSX0JOdcxsBnHPfAxcCj5tZT4LPqyjijdwTxyQlFa+/OwpnmivMh3bJ5CTu69CIiX3SaNOgCk+NW0jXV6fzy7odEYkxFoa+RZtQXASpZUSy5ZfQd5tZo+wH/uTeAegCnBrmuESKJpRN5JGYaa6IQ+OK8qFdt0pZ3rm9Da/cdBYZuw7S9ZXpPDl2AbsPHC5+3PmIhaFv0SYUF0FqGZFs+SX0+4AkM2uevcE5txu4DLg73IGJFEkom8gjMdNcEfv9i/qhbWZ0Pq0Wk/qlcfM5qbw3cxUXD0znq/kbCefIFq0vXjShuAhSy4j8zjmX7xcwH3gYX795GeAlYGZBvxeJr1atWjkRl5XlXK9ezoHve7DH0aaIMW/a9KFLTy/rvv2W37/S08u6TZs+LNThfly93V324hSX+vA4d9e737u12/eG412JRzZt+tDNmJHqvv3W3IwZqYX+dyGxCZjtguTEAsehm1k54DmgFVABGAY855zzfB1CDVsTIKITwYRUEYfGFXdo0pHMLN6ZvoqBE38FoG+nU7jj/PqUSNaEkSKx5LgnljGzUkB/oBNQHnjCOfdJWKIsIiV0AcIzDj1SnPMV8WXLygp7rOt+28ffxyxg0uLNNKtVkWe6teDMeieE9ZgiEjrFWQ/9B2A/0Aa4ALjRzIaHOD6R4xcji7EcIysLrroq57Y+fXzbQzhnfG51TijLm7e15vVbzuK3vYfo/toM/jZ6PruKWTSnNbVjl/528aEwCf0u59z/OecOO+c2Oee6AGPCHZgkmAgtiBI1nIOrr4bx4+GMMyAz82gVfatWxz8hTiGZGZe1qMXEvu25rW19hs1azcUD0hn/y/EVzWlyk9ilv138KDChO+eOadN2zn1QnIOaWWUzG25mi81skZm1NbMqZjbRzJb6v6sNMJGEY7Y3LxV0gTJq1NFkPncu9O0LAwcefdy5c0TWba9QuiRPXn0qox84nxoVU3jgox+5490fWLs995rZ+dPkJrFLf7v44VU1zGDgK+dcU+B0YBHwCDDJOdcYmOR/LIkiHLO9eamgCxTwFevNmXP0fScnH03mY8cWqauguE2mp9WpzOj7z+f/rmzODyu302lQOq9NXs7hQs40p8lNYpf+dvEj4qut+Rd8+Rlo6AIObmZLgA7OuY1mVguY7Jxrkt++VBQXZ2JkQZRCKcqKbcUsjAv1KmcbduznybELmLAwgyY1K/BM95a0Ss2/wUwLs8Qu/e1iT3GK4kKtIbAFeMfMfjKzN/1D42q6o1PNbgRqBPtlM+thZrPNbPaWLVsiF7WEXxQuiHLcCjsdbQgmxAl1k+lJlcsw9I+tGXprK3YfOMw1r83gsVHz2Lkv76I5TW4Su/S3ix9eJPQSwFnAa865M4G9FKF53Tk31DnX2jnXunr16uGKUbwQZQuiFFtBFyghmjM+XE2ml5x6IhP7pnH3BQ345Ps1dBw4mTFz1wctmtO0r7FLf7s4Emy2mXB+AScCqwIetwPGA0uAWv5ttYAlBe1LM8XFkVic7a0gge8h+yvwvYwceey2wN8ZObJQh/HNEMYxXzNmpIbsrcxbt8Nd/dJUl/rwOHfLm9+5VVv3hGzfIlI05DFTXMTv0J1zm4C1ZpbdP94RWAiMBW7zb7sNDY1LLJFYECWSCnP3HaI54yPRZNqidiVG3n8+/7j6VH5as4NLBk3hlW+XceiI5xNGiohfxIviAMzsDOBNoBSwAt9660nAZ0A9YA1wrXNue377UVFcHIm22d6KG0+Ep6Mt7rSwRbFp5wH+OW4BX8zbROMa5enfrSVnN6gSlmPFkkj+DSSxHffUr9FMCV3CprgJOdouUMLgf4sz+NvoBazfsZ/rW9fl0SuaUrlsKa/DCrtgiRsI6UgDkfwooYsURVGGnSWwfYeOMPibpbw5bSWVy5Tk8c7N6HZmbSxOz01eQwTNypCZue2Y12vol4SDErpIUcXTuPgwW7hhF4+NmsfctTs4r1FVnu7agobVy3sdVsjlNWY7b0aHDqozkNBSQhc5Hh6shharsrIcH32/hue+WszBI1k80OFk7u3QkJQSyV6HFjKTJycBhf/M1B26hEM0TSwjEhvibVx8mCUlGbecm8qkfmlceuqJDPrmVy4fPJWZy49tio5VKSn1gm4vUaKqJmcRzymhiwQToklfElGNCqV56cYzefeONhzOzOLG/3xHv89+ZvveQ16HVmx5DRFs3HiwJmcRz6nJXSSYCA87i1f7D2Xy0v+WMnTKCiqULsFjVzTjD63qxHTRnIanidfUhy5SFAkw7CySlmzazeOj5jF79W+c06AK/bu15OQa8Vc0JxIJ6kMXKQoz3x147qSd1/ZsBa2DXpQL6FDuy+PjNDmxAi91W8ndpw9j3to1XDpoEv8cNYIDhzOLvW8R8VFCFwmlgtZBL8oUtqHcl8fHycgYxtJfe3BBrY95tt29nH3iVN6eVZpOA8YzfdnWYu9fRJTQRUKra9dji+cCi+sKOT97yPfl8XECl3itlLKDe04fwJ9bP8Hhw9u4+c1Z9Pl0Llv3HCz2cUQSmfrQRUItlBPSRGpymzAfJ6/x24cyU5iX+TOvpy+nbKkSPHp5U65rXZekJNUniORFRXEikRTKCWnCOblNYJEf5DzOiBH51wsUQV4zrGVPvLJs824eGzWf71dup039E+jfrSWn1KxQ7OOKxCMVxUn4RaqIK9oFm5Cmd++c77+w5yTck9tk95/37u37CnTNNb4YQ6CgJV5PrlGBT3ucy7//cBpLN+/hisFTef7rxSqaEymKYIukx8pXq1atjn+FeAm9kSOdA+d69XIuK8u3LSvL9xh8z8e7wPfbq5dzI0b4fgbnevb0PV/Yc5J7X8EehyLenj1zxpj7cSiO45zbtOlDN2NGqvv2W3MzZqS6TZs+DPq6rbsPuL6fznWpD49z7Z77n5u8ZHNIji8SL4DZLkhO9DwpF+dLCT3KRCIBRbvcFzVZWc499NDRBDlixNFz0rOn73Fe5yVSF0iBFx3BErtHF2LTl21xFz7/rUt9eJx76KMfXcau/Z7EIRJt8kro6kOX0HIJvkKZCzLxzMiRvubrQD17+r4PGZL3rHPB9pXf9uLEPGpUzhiz/CuEeTyJzsEjmbw2eTmvfruclJJJPHxZU246u56K5iShqShOIsdphbIcnPP1Tw8ZcnRbz56+x9FwsRMDF2HLt+zhiVHzmbliG2fVq8wz3VvS9MSKEY9D075KNFBRnERGdnIIVJQiruy7xdyvz2t7rBoyxJfUvU6agck8ihehaVS9PB/96RwGXHs6q7bto/OQaTz75SL2HToS9PUZGcOYObM+kycnMXNmfTIyhhU7hoyMYSxZ0sNfre84eHA1S5b0CMm+RUJBCV1CJxTJIVKzo0VKduzZCTy/13lxwTJ69NG/V/bFxaBBR/9ux3O+w3RRZmZc06oOk/qmcc1ZtXkjfQWXDJrCt4s353hduBJv4OQ42bKy9rFixePF2q9IqCihS+iEIjlEana0SMk+J8GS+ZAhRxOcVxcsXbv6+vADWwqy/24jRx7f+Q7zRdkJ5Urx7z+czuvX7sYdXsEd7/7A9UOeYv7yj4DwJd6DB9cUabtIpKkPXUInVEVcMdCnW2jZd6Xp6b4E3rkzNGwIL73ke/6hh3zfX3rJl/RffDH23mNuuS/CBg069nEx32P2XfihI4f4YmV3xi6/gZJJR3igHTQvdSNJFmz8utGhQ9ZxH7OgyXFEIkVFcRJb4qmwLntt9c6dYfx4X+J27mhSzzZihO918SDMF2W5k2vG3lq8v/B+Fmw7k0aVV/HH5gNIrbgyx+8UN/FmX0QE3v0nJZWlSZOhUVEYp4K9xKGiOIkdxS2sizbZzdpjx/qS2pAhxya1nj2DD12LVdnN9oFC2MKSu5m7ZrmN/Ln137jntBfYfqge/5j5Ip8svpMDR0oDOWelO141a95MkyZDSUlJBYyUlNSQJfPiFvGpYE8ASngdgEiOJnk4emfXsyekpfmaq7Pv9GKx2T17DXXwxe9cziFs8Sivi7IQ/f1SUuod0/xtBh0arOT+rpfx91GfM3ped77f1I47Tx/OtefdmGfiLcqdbc2aN4f8rjf3nX92Ms4+XmHkVzegu/TEoTt0CZ3jrW4OLKIaNSpnEdk11/iSenGqrqNd9pj0WG6FCBSBoXD5zQ1fqWxJXry5O8PvbUu1Sg14YdZ9/N+EJmzcuf+Y/UTDnW0oivhUsCeghC6hVJjq5mDJvWtXX1IbPBgmT/b1JcPRiVe6dSte1XU0GTUq+N159vuPhwuWcAyFy6Uwzd+t61dh3EPt+OtlTUj/dQsXD0jnnekrycw6+m8vGoaihSIZp6TUK9J2iU9K6BI6hRlyFizpB3rpJd9dee5Z1LKbrWOtuT2Qc77uA/Al8Ow71+wEP2JEbF+wZF+sdemScyhcdpfKwIEhvSirWfNm2rZdRYcOWbRtuypo03KpEknc3+FkJvROo3X9Kvzj84V0fWU689btBPJJpgdWF9jaFKrJa/JOukmF3mdBq9lJYlBCl9DJfSeWlHTsnVpeST/YxCux2F+en9Gjj16oZA9Pyz5f2YVy4Xy/4Z6FL/tirW/fo0MUA1toxozx7KKsXtWyvHtHG16+6Uw27TpAl1em8Y/PF5CV1Djo62vNqp5va9OOd/uErKk+WDL2ySz0PsNZsCexQ8PWJPQKGnIWbEhT4GIl2WJ17HleIrXYSl6yh88FntfAv0Vei8QUVgTGn4fCzv2HeeHrJXw4azXVymVx0ykDOLNG+u/PJyWVpckpb1DzX7PzfC8zrxvFwUPH3t0f79C4jIxhLFp0G3Ds+HmNc5fcNGxNIqMwQ86CDWmCo3evUTqfeLHl1W0Qqe6EcM/CV5gWmuIKQStDpTIleaprC0bcdx5Vy1di8I9/4aW5z7Btf42jd7Yn3pLvezl4aG3QfR9vEZrvTjr4pDcqbJNCC7amaqx8aT30KFPY9dADt+degzuc635L8HNfnLXqs7J8f5/A38/Kyrn/4913MCFeI/7QkUz3Rvoy1/SJL12zv33p/jNluTt8JLPA9zJjRqr79luO+ZoxI/W431o49inxiTzWQ9cduoROYaqbgw1pCjbPeXHnE5fgQj3hS+4iR+dfKjZQKFtZQtzKUDI5iR7tGzGxb3vObViVp8cv4uqXpzN3zW++f3u530vv3jByJA0bPB3yIjQVtkmxBcvykfgCkoGfgHH+x1WAicBS//cTCtqH7tCjTLC7tdzbQ3yHJUUUjjv07P317On7CmxxyX5cnGOE+z38vtss98UvG9zZ/Se6+g9/7v7v4nvczlJlj7YcBb63ESPcpk0f+u+qzc2Ykeo2bfqw2G8tHPuU+EMed+heJvS+wEcBCf3fwCP+nx8BnitoH0roMagwSV/Co7BdIsXZb+7uk3BdrIWxWX/X/kPu7wNHu/p/Heva3P+eG9+7v8vKzDwmoYt4JaoSOlAHmARcFJDQlwC1/D/XApYUtB8ldEk4xbkgCmfrSH4JNtQXa2G6Q899jLnvjXRX/OUjl/rwOHf7H/7u1lSs4UvqI0bowlM8FW0JfTjQCugQkNB35HrNbwXtRwldEk5xknK4WkcikWCDHSuUrQx5OHz4iPtP6y6uWZ//uiZ9h7vXvl3qDgUWzUWSWrfEL2oSOnAl8Kr/5yIndKAHMBuYXa9evTCdLpEoFeGEFnXxRLIGI2C/6ytUc3d3e9ylPjzOXToo3c1etT10xymswrx3Jf2EEE0J/VlgHbAK2ATsAz5Uk7tIIUXyjrggkS5yjFTCyuNC5avG57pz/zrc1X9knHts5C9ux75DoTleMWLK8VhFpwkhahJ6joPnvEN/PldR3L8L+n0ldElY4RzrXdQ44vGOMJ/EuLtUGffPQWNcg0fGuVZPTXRj5q53WZF6nwVdzEVbC46ERV4J3dOpX82sA/Bn59yVZlYV+AyoB6wBrnXObc/v9zX1qyQk546dOjeKplaNC84VOE3v/A27eGzUPH5Zt5N2javxdNcWpFYtF5nYijq1sv59xJW8pn7VXO4isSTwwzqK50tPFJlZjg9mruKFCb9yODOLnh0b86d2DSlVIkxzdhU2WReU9CWmaS53kVjmnG+u8lGjciZvgPbt42s99RiSnGTcfn4DvumbxkVNa/D810u48qWp/LAq38bF45P7Yi6vNQ+yXxcontZEkLwFa4ePlS/1oUvCyO7TDRwHHdg/OmJEbPdZx4lvFm5y5z07yaU+PM49PPxn99veg6HbeWGr3NWHHveIxqK44n4poUvC0Ad1zNh78LDrP36ha/joeHfWPye4kT+uDU3RnKZWFr+8Err60EVihYqdYspCf9Hc3LU7OP/kqjzdtSUNqoW5aM4VXMynfyuxT0VxIvFAxU4xJTPL8dGs1fz7qyUczMziwQtP5p60hqSUSPY6NIlhKooTiXUqdoo5yUnGrW3rM6lfGp2a12TgxF+5YvBUvluxzevQJA4poYvEgsJWOEtUqlGxNK/cdBbv3tGGQ5lZ3DD0O/7y35/ZvveQ16FJHFFCF4kFo0cfO9Z80KCjSV3D1WJChyY1mNA7jfs6NGLUT+vpOGAyw+esI5a7PiV6qA9dJBao2CnuLN60i8dHzWfO6t84t2EV+ndrSaPq5b0OS2KAiuJERKJMVpbjkx/W8q8vF3HgcBb3dWjEfR0aUbqkiuYkbyqKExGJMklJxk3n1GNSvw5c3vJEBk9ayuWDpzJj2VavQ5MYpIQuIrHF+afBzd26mNf2GFC9QgqDbziTD+46myznuOnNWfT9dC7b9hz0OjSJIUroIhJbRo+G7t2Dz1/evXtMFwi2a1ydr3u358ELT+bzXzbQcWA6n/6whqys2LtIkchTQheR2NK167FD9gKH9HXt6nWExVK6ZDJ/vrQJX/Rsxyk1KvDwiHncMPQ7lmbs9jo0iXIqihOR2JMg0+BmZTmGz1nHM18uYu/BI9zTvhEPXnSyiuYSnKrcRSS+JNA0uNv2HKT/F4sY+eN6UquW5emuLWjXuLrXYYlHVOUuIvEjwabBrVo+hYHXncFHd59Dkhm3vvU9vT75iS27VTQnRymhi0hsSeBpcM87uRpf9mpHr46N+XLeJjoOmMxHs1Q0Jz5K6CISWxJ8GtzSJZPp0+kUvuzdjuYnVeSxUfO49o2ZLN60y+vQxGPqQxeR2KJpcH/nnGPkj+t5evxCdh84wp/aN6TnRY0pU0pFc/FMRXEiInFq+95DPPvFIv47Zx11q5Thn11acGGTGl6HJWGiojgRkThVpVwpnr/2dD7pcS6lkpO4450feOCjH9m864DXoUkEKaGLiMSJcxtW5Yte7ejX6RQmLsyg44B0Ppi5ikwVzSUEJXQRkTiSUiKZhzo25uve7TmtbiX+NmYB17w2g4UbVDQX75TQRUTiUINq5fjwrnN48fozWLt9H1e9PI1nvljEvkNHvA5NwkQJXUQkTpkZXc+szaR+aVzXug5Dp6yg08ApTFqU4XVoEgZK6CIica5y2VI82/00/ntvW8qlJHPXe7O594M5bNqporl4ooQuIpIg2tSvwriH2vGXS5vw7ZLNXDwwnXenr1TRXJxQQhcRSSClSiTxwIUnM6FPe85KPYEnP19It1enM3/9Tq9Dk2JSQhcRSUCpVcvx3h1tGHLjmWzYcYCrX57GPz9fyJ6DKpqLVUroIiIJysy4+vSTmNQvjRvPrsc7M1bSaWA6Xy/Y5HVochyU0EVEElylMiXp360lw+89j0plSnLPB3P40/uz2bBjv9ehSREooYuICACtUk/g84cu4NHLmzJ16RYuHpjOm1NXcCQzy+vQpBAintDNrK6ZfWtmi8xsgZn18m+vYmYTzWyp//sJkY5NRCTRlUxO4p60Rkzsk8Y5Darw9PhFdHllOj+v3eF1aFIAL+7QjwD9nHPNgHOBB8ysOfAIMMk51xiY5H8sIiIeqFulLG/f3oZXbz6LLbsP0vXV6fx9zHx2HzjsdWiSh4gndOfcRufcj/6fdwOLgNpAF+A9/8veA7pGOjYRETnKzLiiZS2+6ZfGH89N5f3vVnPxwHS+nLeRWF56O1552oduZvWBM4FZQE3n3EbwJX1Ai/mKiESBiqVL8o8uLRh1//lULZfCfcN+5K73ZrN2+z6vQ5MAniV0MysPjAB6O+cKvQyQmfUws9lmNnvLli3hC1BERHI4o25lxj54Pk90bsZ3K7ZxyaApvJG+nMMqmosKniR0MyuJL5kPc86N9G/OMLNa/udrAZuD/a5zbqhzrrVzrnX16tUjE7CIiABQIjmJu9s1ZGLfNM4/uRrPfrmYq16axo9rfvM6tITnRZW7AW8Bi5xzAwOeGgvc5v/5NmBMpGMTEZHCqV25DG/e1po3bm3Fjn2Huea1GTwxeh4796tozisW6cIGM7sAmArMA7LbaR7D14/+GVAPWANc65zbnt++Wrdu7WbPnh3GaEVEpCB7Dh5hwIQlvDdjFVXLp/B/VzbnytNq4bt/k1AzsznOudbHbI/lSkUldBGR6DFv3U4eGzWPeet3knZKdZ7q0oJ6Vct6HVbcySuha6Y4EREJiZZ1KjH6gfP5+1XNmb1qO50GpfPq5GUqmosQJXQREQmZ5CTjjvMb8E2/NC5sUoN/f7WEzkOmMntVvj2oEgJK6CIiEnK1KpXh9Vtb8eYfW7P3YCZ/eH0mj46cx859KpoLFyV0EREJm4ub12RCn/b8qV0DPpu9lo4DJzNm7nrNNBcGSugiIhJW5VJK8Hjn5ox98Hxqn1CWXp/M5da3vmfV1r1ehxZXlNBFRCQiTj2pEiPvO4+nupzKz2t3cMmLU3hp0lIOHVHRXCgooYuISMQkJxm3tq3PN/3S6NSsJgMm/soVQ6Yya8U2r0OLeUroIiIScTUrluaVm8/indvbcOBwJtcP/Y6/Dv+Z3/Ye8jq0mKWELiIinrmwaQ0m9knj3rRGjPxxPR0HpjNizjoVzR0HJXQREfFUmVLJPHJ5U8b1vID6VcvS778/c9N/ZrFiyx6vQ4spSugiIhIVmp5YkeH3nkf/bi2Yv2Enl704lRe/+ZWDRzK9Di0mKKGLiEjUSEoybj4nlUn90risxYm8+M1SLn9xKjOWb/U6tKinhC4iIlGnRoXSDLnxTN6/82yOZDlu+s8s+n42l217DnodWtRSQhcRkajV/pTqTOjTngcubMTYuRvoODCdz2avVdFcEEroIiIS1UqXTOYvlzbli17taFyjPH8d/gvXD/2OZZt3ex1aVFFCFxGRmHBKzQp82qMtz13TkiWbdnP54KkMmLCEA4dVNAdK6CIiEkOSkozr29RjUr80rjrtJF763zIue3EK05aqaE4JXUREYk618ikMvP4Mht19DgC3vDWL3p/8xNYELppTQhcRkZh1/snV+Kp3e3p2bMz4eRu56IXJfPz9GrKyEq9oTgldRERiWumSyfTtdApf9mpPs1oVeXTkPK57YyZLNiVW0ZwSuoiIxIWTa5Tnkx7n8vwfTmP5lj10HjKV575azP5DiVE0p4QuIiJxw8y4tnVdJvXrQNcza/Pa5OVc8mI6k5ds9jq0sFNCFxGRuFOlXCleuPZ0Pv7TuZRMTuL2d37gwY9+ZPOuA16HFjZK6CIiErfaNqrKl73a0efiU5iwMIOOA9P54LvVcVk0p4QuIiJxLaVEMr0ubsxXvdrRsnYl/jZ6Pte8PoNFG3d5HVpIKaGLiEhCaFi9PMPuPodB15/O6m37uPKlaTz7xSL2HTridWghoYQuIiIJw8zodmYd/tcvjWtb1eGNKSvoNHAK/1uc4XVoxaaELiIiCady2VL865rT+OyetpQtlcyd787m/mFzyIjhojkldBERSVhnN6jC+J7t+MulTZi0aDMdB6Tz7vSVZMZg0ZwSuoiIJLRSJZJ44MKTmdCnPWfWq8yTny+k26vTmb9+p9ehFYkSuoiICJBatRzv33k2g284gw07DnD1y9N4atxC9h6MjaI5JXQRERE/M6PLGbWZ1DeNG86ux1vTVtJpYDoTFmzyOrQCKaGLiIjkUqlsSZ7p1pIR97WlQumS9PhgDj3en82GHfu9Di1PUZfQzewyM1tiZsvM7BGv4xERkcTVKrUK43pewCOXN2XK0i10GpjOW9NWciQzy+vQjhFVCd3MkoFXgMuB5sCNZtbc26hERCSRlUxO4t60Rkzsk0abBlV4atxCur46nV/W7fA6tByiKqEDZwPLLBWjDwAABcJJREFUnHMrnHOHgE+ALh7HJCIiQt0qZXnn9ja8ctNZZOw6SNdXpvPk2AXsPnDY69CA6EvotYG1AY/X+beJiIh4zszofFotJvVL45ZzU3lv5iouHpjOV/M34py3Y9dLeHr0Y1mQbTnOkJn1AHr4Hx40s/lhjyq2VAO2eh1ElNE5yUnn41g6J8fSOckpz/OxCrj88YjGkhpsY7Ql9HVA3YDHdYANgS9wzg0FhgKY2WznXOvIhRf9dE6OpXOSk87HsXROjqVzklMsnI9oa3L/AWhsZg3MrBRwAzDW45hERESiXlTdoTvnjpjZg8DXQDLwtnNugcdhiYiIRL2oSugAzrkvgC8K+fKh4YwlRumcHEvnJCedj2PpnBxL5ySnqD8f5nVVnoiIiBRftPWhi4iIyHGI2YSe6FPEmlldM/vWzBaZ2QIz6+XfXsXMJprZUv/3E7yONdLMLNnMfjKzcf7HCX1OzKyymQ03s8X+fy9tE/mcmFkf//+Z+Wb2sZmVTrTzYWZvm9nmwGG/+Z0DM3vU/1m7xMwu9Sbq8MrjnDzv/3/zi5mNMrPKAc9F3TmJyYSuKWIBOAL0c841A84FHvCfg0eASc65xsAk/+NE0wtYFPA40c/JYOAr51xT4HR85yYhz4mZ1QZ6Aq2dcy3wFd/eQOKdj3eBy3JtC3oO/J8rNwCn+n/nVf9ncLx5l2PPyUSghXPuNOBX4FGI3nMSkwkdTRGLc26jc+5H/8+78X1I18Z3Ht7zv+w9oKs3EXrDzOoAnYE3AzYn7Dkxs4pAe+AtAOfcIefcDhL4nOArBi5jZiWAsvjmukio8+GcmwJsz7U5r3PQBfjEOXfQObcSWIbvMziuBDsnzrkJzrnsxdC/wzc3CkTpOYnVhK4pYgOYWX3gTGAWUNM5txF8SR+o4V1knngR+CsQuBRSIp+ThsAW4B1/N8SbZlaOBD0nzrn1wAvAGmAjsNM5N4EEPR+55HUO9Hnrcyfwpf/nqDwnsZrQC5wiNlGYWXlgBNDbObfL63i8ZGZXApudc3O8jiWKlADOAl5zzp0J7CX+m5Pz5O8X7gI0AE4CypnZLd5GFfUS/vPWzB7H1805LHtTkJd5fk5iNaEXOEVsIjCzkviS+TDn3Ej/5gwzq+V/vhaw2av4PHA+cLWZrcLXDXORmX1IYp+TdcA659ws/+Ph+BJ8op6Ti4GVzrktzrnDwEjgPBL3fATK6xwk9Oetmd0GXAnc7I6O847KcxKrCT3hp4g1M8PXL7rIOTcw4KmxwG3+n28DxkQ6Nq845x51ztVxztXH92/if865W0jsc7IJWGtmTfybOgILSdxzsgY418zK+v8PdcRXf5Ko5yNQXudgLHCDmaWYWQOgMfC9B/FFnJldBjwMXO2c2xfwVFSek5idWMbMrsDXX5o9RWx/j0OKKDO7AJgKzONof/Fj+PrRPwPq4fvwutY5l7v4Je6ZWQfgz865K82sKgl8TszsDHxFgqWAFcAd+C7mE/KcmNk/gOvxNaH+BNwNlCeBzoeZfQx0wLeCWAbwd2A0eZwDf5PznfjOWW/n3JdBdhvT8jgnjwIpwDb/y75zzt3rf33UnZOYTegiIiJyVKw2uYuIiEgAJXQREZE4oIQuIiISB5TQRURE4oASuoiISBxQQheR42JmX5nZjuxV7UTEW0roInK8ngdu9ToIEfFRQheRfJlZG/960KXNrJx/LfEWzrlJwG6v4xMRnxJeByAi0c0594OZjQWeBsoAHzrn5nsclojkooQuIoXxT3xrKBwAenoci4gEoSZ3ESmMKvjmO68AlPY4FhEJQgldRApjKPA3fOtBP+dxLCIShJrcRSRfZvZH4Ihz7iMzSwZmmNlFwD+ApkB5M1sH3OWc+9rLWEUSmVZbExERiQNqchcREYkDSugiIiJxQAldREQkDiihi4iIxAEldBERkTighC4iIhIHlNBFRETigBK6iIhIHPh/sBAgLer1wfgAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(8,5))\n",
    "ax.scatter(positive['exam1'], positive['exam2'], c='y', label='Admitted')\n",
    "ax.scatter(negetive['exam1'], negetive['exam2'], s=50, c='r', marker='x', label='Not Admitted')\n",
    "ax.plot(x1, x2)\n",
    "ax.set_xlim(0, 130)\n",
    "ax.set_ylim(0, 130)\n",
    "ax.set_xlabel('x1')\n",
    "ax.set_ylabel('x2')\n",
    "ax.set_title('Decision Boundary')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 正则化逻辑会回归\n",
    "简而言之，正则化是成本函数中的一个术语，它使算法更倾向于“更简单”的模型（在这种情况下，模型将更小的系数）。这个理论助于减少过拟合，提高模型的泛化能力。\n",
    "\n",
    "设想你是工厂的生产主管，你有一些芯片在两次测试中的测试结果。对于这两次测试，你想决定是否芯片要被接受或抛弃。为了帮助你做出艰难的决定，你拥有过去芯片的测试数据集，从其中你可以构建一个逻辑回归模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Test 1</th>\n",
       "      <th>Test 2</th>\n",
       "      <th>Accepted</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.051267</td>\n",
       "      <td>0.69956</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.092742</td>\n",
       "      <td>0.68494</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.213710</td>\n",
       "      <td>0.69225</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.375000</td>\n",
       "      <td>0.50219</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.513250</td>\n",
       "      <td>0.46564</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     Test 1   Test 2  Accepted\n",
       "0  0.051267  0.69956         1\n",
       "1 -0.092742  0.68494         1\n",
       "2 -0.213710  0.69225         1\n",
       "3 -0.375000  0.50219         1\n",
       "4 -0.513250  0.46564         1"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "path =  'ex2data2.txt'\n",
    "data2 = pd.read_csv(path, header=None, names=['Test 1', 'Test 2', 'Accepted'])\n",
    "data2.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgAAAAE9CAYAAAB9dNoUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de5xcVZn/+8+TAKKdlgwkIDZEookXkkliEoJoxsYDEcwgJIzaMB5BxYGoOASOSvx5HJnxgoP8wOggiJERZkaIlySi4ohyCRP5SUgcLgmXpEE4JkGTDgrdGUFIP+ePXTtdXV1VXd1V+/59v179qq59qVq7bvvZaz1rLXN3REREpFjGJF0AERERiZ8CABERkQJSACAiIlJACgBEREQKSAGAiIhIASkAEBERKaD9ki5AnCZMmOBHHXVU0sUQERGJxcaNG3vcfWK1dYUKAI466ig2bNiQdDFERERiYWZP1lqnJgAREZECUgAgIiJSQAoARERECqhQOQAiIpI+L7zwAtu2beO5555LuiiZdeCBB3LEEUew//77N7yPAgAREUnUtm3baG9v56ijjsLMki5O5rg7u3fvZtu2bUyePLnh/dQEICIiiXruuec45JBDdPIfJTPjkEMOGXENigIAkYxwd3btWk3lFN61lotkiU7+zRnN66cAQCQjenrWsHnz6XR3X7jvZO/udHdfyObNp9PTsybhEopk2+rVqzEzHnnkkVie74tf/OKI9/n2t7/N+eef35LnVwAgkhETJiyio+MCtm9fvi8I6O6+kO3bl9PRcQETJixKuogisejthRUr4OKLg9ve3tY87o033sj8+fO56aabWvOAwxhNANBKCgBEMsLMmDLlyn1BwNq1Y/ad/KdMuVJVqHWo+SQ/1q2Djg5YuhQuuyy47egIljejr6+PX/7yl3zrW9/aFwDs3buXj3/84/zlX/4lM2bM4Gtf+xoA9957L29+85uZOXMm8+bNo7e3l7179/KJT3yCY445hhkzZvCNb3wDgDvvvJO3vvWtLF68mKOPPpolS5bQ39/PsmXL+NOf/sSsWbN473vfC8C///u/M2/ePGbNmsV5553H3r17AfjXf/1XXvva19LZ2ckvf/nL5g60nLsX5m/OnDkuknX9/f1+xx3s++vv70+6SKm3c+cqv+MOfMuWC/a9Xv39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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_data():\n",
    "    positive = data2[data2['Accepted'].isin([1])]\n",
    "    negative = data2[data2['Accepted'].isin([0])]\n",
    "\n",
    "    fig, ax = plt.subplots(figsize=(8,5))\n",
    "    ax.scatter(positive['Test 1'], positive['Test 2'], s=50, c='b', marker='o', label='Accepted')\n",
    "    ax.scatter(negative['Test 1'], negative['Test 2'], s=50, c='y', marker='x', label='Rejected')\n",
    "    ax.legend()\n",
    "    ax.set_xlabel('Test 1 Score')\n",
    "    ax.set_ylabel('Test 2 Score')\n",
    "    \n",
    "plot_data()\t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意到其中的正负两类数据并没有线性的决策界限。因此直接用logistic回归在这个数据集上并不能表现良好，因为它只能用来寻找一个线性的决策边界。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 特征映射\n",
    "多项式的特征映射：如果样本量多，逻辑回归问题很复杂，而原始特征只有x1,x2可以用多项式创建更多的特征x1、x2、x1x2、x1^2、x2^2、... X1^nX2^n。因为更多的特征进行逻辑回归时，得到的分割线可以是任意高阶函数的形状。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "polynomial expansion\n",
    "\n",
    "```\n",
    "for i in 0..i\n",
    "  for p in 0..i:\n",
    "    output x^(i-p) * y^p\n",
    "```\n",
    "$ mapFeature=\n",
    "{\\begin{bmatrix}\n",
    "1\\\\\n",
    "x_1\\\\\n",
    "x_2\\\\\n",
    "x_1^2\\\\\n",
    "x_1x_2\\\\\n",
    "x_2^2\\\\\n",
    "x_1^3\\\\\n",
    "\\vdots\\\\\n",
    "x_1x_2^5\\\\\n",
    "x_2^6\n",
    "\\end{bmatrix}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "def feature_mapping(x1, x2, power):\n",
    "    data = {}\n",
    "    for i in np.arange(power + 1):\n",
    "        for p in np.arange(i + 1):\n",
    "            data[\"f{}{}\".format(i - p, p)] = np.power(x1, i - p) * np.power(x2, p)\n",
    "\n",
    "    return pd.DataFrame(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "x1 = data2['Test 1'].values\n",
    "x2 = data2['Test 2'].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>f00</th>\n",
       "      <th>f10</th>\n",
       "      <th>f01</th>\n",
       "      <th>f20</th>\n",
       "      <th>f11</th>\n",
       "      <th>f02</th>\n",
       "      <th>f30</th>\n",
       "      <th>f21</th>\n",
       "      <th>f12</th>\n",
       "      <th>f03</th>\n",
       "      <th>...</th>\n",
       "      <th>f23</th>\n",
       "      <th>f14</th>\n",
       "      <th>f05</th>\n",
       "      <th>f60</th>\n",
       "      <th>f51</th>\n",
       "      <th>f42</th>\n",
       "      <th>f33</th>\n",
       "      <th>f24</th>\n",
       "      <th>f15</th>\n",
       "      <th>f06</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>0.051267</td>\n",
       "      <td>0.69956</td>\n",
       "      <td>0.002628</td>\n",
       "      <td>0.035864</td>\n",
       "      <td>0.489384</td>\n",
       "      <td>0.000135</td>\n",
       "      <td>0.001839</td>\n",
       "      <td>0.025089</td>\n",
       "      <td>0.342354</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000900</td>\n",
       "      <td>0.012278</td>\n",
       "      <td>0.167542</td>\n",
       "      <td>1.815630e-08</td>\n",
       "      <td>2.477505e-07</td>\n",
       "      <td>0.000003</td>\n",
       "      <td>0.000046</td>\n",
       "      <td>0.000629</td>\n",
       "      <td>0.008589</td>\n",
       "      <td>0.117206</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.092742</td>\n",
       "      <td>0.68494</td>\n",
       "      <td>0.008601</td>\n",
       "      <td>-0.063523</td>\n",
       "      <td>0.469143</td>\n",
       "      <td>-0.000798</td>\n",
       "      <td>0.005891</td>\n",
       "      <td>-0.043509</td>\n",
       "      <td>0.321335</td>\n",
       "      <td>...</td>\n",
       "      <td>0.002764</td>\n",
       "      <td>-0.020412</td>\n",
       "      <td>0.150752</td>\n",
       "      <td>6.362953e-07</td>\n",
       "      <td>-4.699318e-06</td>\n",
       "      <td>0.000035</td>\n",
       "      <td>-0.000256</td>\n",
       "      <td>0.001893</td>\n",
       "      <td>-0.013981</td>\n",
       "      <td>0.103256</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.213710</td>\n",
       "      <td>0.69225</td>\n",
       "      <td>0.045672</td>\n",
       "      <td>-0.147941</td>\n",
       "      <td>0.479210</td>\n",
       "      <td>-0.009761</td>\n",
       "      <td>0.031616</td>\n",
       "      <td>-0.102412</td>\n",
       "      <td>0.331733</td>\n",
       "      <td>...</td>\n",
       "      <td>0.015151</td>\n",
       "      <td>-0.049077</td>\n",
       "      <td>0.158970</td>\n",
       "      <td>9.526844e-05</td>\n",
       "      <td>-3.085938e-04</td>\n",
       "      <td>0.001000</td>\n",
       "      <td>-0.003238</td>\n",
       "      <td>0.010488</td>\n",
       "      <td>-0.033973</td>\n",
       "      <td>0.110047</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.375000</td>\n",
       "      <td>0.50219</td>\n",
       "      <td>0.140625</td>\n",
       "      <td>-0.188321</td>\n",
       "      <td>0.252195</td>\n",
       "      <td>-0.052734</td>\n",
       "      <td>0.070620</td>\n",
       "      <td>-0.094573</td>\n",
       "      <td>0.126650</td>\n",
       "      <td>...</td>\n",
       "      <td>0.017810</td>\n",
       "      <td>-0.023851</td>\n",
       "      <td>0.031940</td>\n",
       "      <td>2.780914e-03</td>\n",
       "      <td>-3.724126e-03</td>\n",
       "      <td>0.004987</td>\n",
       "      <td>-0.006679</td>\n",
       "      <td>0.008944</td>\n",
       "      <td>-0.011978</td>\n",
       "      <td>0.016040</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.513250</td>\n",
       "      <td>0.46564</td>\n",
       "      <td>0.263426</td>\n",
       "      <td>-0.238990</td>\n",
       "      <td>0.216821</td>\n",
       "      <td>-0.135203</td>\n",
       "      <td>0.122661</td>\n",
       "      <td>-0.111283</td>\n",
       "      <td>0.100960</td>\n",
       "      <td>...</td>\n",
       "      <td>0.026596</td>\n",
       "      <td>-0.024128</td>\n",
       "      <td>0.021890</td>\n",
       "      <td>1.827990e-02</td>\n",
       "      <td>-1.658422e-02</td>\n",
       "      <td>0.015046</td>\n",
       "      <td>-0.013650</td>\n",
       "      <td>0.012384</td>\n",
       "      <td>-0.011235</td>\n",
       "      <td>0.010193</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 28 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   f00       f10      f01       f20       f11       f02       f30       f21  \\\n",
       "0  1.0  0.051267  0.69956  0.002628  0.035864  0.489384  0.000135  0.001839   \n",
       "1  1.0 -0.092742  0.68494  0.008601 -0.063523  0.469143 -0.000798  0.005891   \n",
       "2  1.0 -0.213710  0.69225  0.045672 -0.147941  0.479210 -0.009761  0.031616   \n",
       "3  1.0 -0.375000  0.50219  0.140625 -0.188321  0.252195 -0.052734  0.070620   \n",
       "4  1.0 -0.513250  0.46564  0.263426 -0.238990  0.216821 -0.135203  0.122661   \n",
       "\n",
       "        f12       f03  ...       f23       f14       f05           f60  \\\n",
       "0  0.025089  0.342354  ...  0.000900  0.012278  0.167542  1.815630e-08   \n",
       "1 -0.043509  0.321335  ...  0.002764 -0.020412  0.150752  6.362953e-07   \n",
       "2 -0.102412  0.331733  ...  0.015151 -0.049077  0.158970  9.526844e-05   \n",
       "3 -0.094573  0.126650  ...  0.017810 -0.023851  0.031940  2.780914e-03   \n",
       "4 -0.111283  0.100960  ...  0.026596 -0.024128  0.021890  1.827990e-02   \n",
       "\n",
       "            f51       f42       f33       f24       f15       f06  \n",
       "0  2.477505e-07  0.000003  0.000046  0.000629  0.008589  0.117206  \n",
       "1 -4.699318e-06  0.000035 -0.000256  0.001893 -0.013981  0.103256  \n",
       "2 -3.085938e-04  0.001000 -0.003238  0.010488 -0.033973  0.110047  \n",
       "3 -3.724126e-03  0.004987 -0.006679  0.008944 -0.011978  0.016040  \n",
       "4 -1.658422e-02  0.015046 -0.013650  0.012384 -0.011235  0.010193  \n",
       "\n",
       "[5 rows x 28 columns]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_data2 = feature_mapping(x1, x2, power=6)\n",
    "_data2.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "经过映射，我们将有两个特征的向量转化成了一个28维的向量。\n",
    "\n",
    "在这个高维特征向量上训练的logistic回归分类器将会有一个更复杂的决策边界，当我们在二维图中绘制时，会出现非线性。\n",
    "\n",
    "虽然特征映射允许我们构建一个更有表现力的分类器，但它也更容易过拟合。在接下来的练习中，我们将实现正则化的logistic回归来拟合数据，并且可以看到正则化如何帮助解决过拟合的问题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正则化逻辑回归代价函数\n",
    "$$ J\\left( \\theta  \\right)=\\frac{1}{m}\\sum\\limits_{i=1}^{m}{[-{{y}^{(i)}}\\log \\left( {{h}_{\\theta }}\\left( {{x}^{(i)}} \\right) \\right)-\\left( 1-{{y}^{(i)}} \\right)\\log \\left( 1-{{h}_{\\theta }}\\left( {{x}^{(i)}} \\right) \\right)]}+\\frac{\\lambda }{2m}\\sum\\limits_{j=1}^{n}{\\theta _{j}^{2}}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意：不惩罚第一项${\\theta}_0$\n",
    "\n",
    "先获取特征，标签以及参数theta，确保维度良好。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((118, 28), (118,), (28,))"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这里因为做特征映射的时候已经添加了偏置项，所以不用手动添加了。\n",
    "X = _data2.values  \n",
    "y = data2['Accepted'].values\n",
    "theta = np.zeros(X.shape[1])\n",
    "X.shape, y.shape, theta.shape  # ((118, 28), (118,), (28,))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正则化梯度下降\n",
    "因为我们未对${{\\theta }_{0}}$ 进行正则化，所以梯度下降算法将分两种情形：\n",
    "\\begin{align}\n",
    "  & Repeat\\text{ }until\\text{ }convergence\\text{ }\\!\\!\\{\\!\\!\\text{ } \\\\ \n",
    " & \\text{     }{{\\theta }_{0}}:={{\\theta }_{0}}-a\\frac{1}{m}\\sum\\limits_{i=1}^{m}{[{{h}_{\\theta }}\\left( {{x}^{(i)}} \\right)-{{y}^{(i)}}]x_{_{0}}^{(i)}} \\\\ \n",
    " & \\text{     }{{\\theta }_{j}}:={{\\theta }_{j}}-a\\frac{1}{m}\\sum\\limits_{i=1}^{m}{[{{h}_{\\theta }}\\left( {{x}^{(i)}} \\right)-{{y}^{(i)}}]x_{j}^{(i)}}+\\frac{\\lambda }{m}{{\\theta }_{j}} \\\\ \n",
    " & \\text{          }\\!\\!\\}\\!\\!\\text{ } \\\\ \n",
    " & Repeat \\\\ \n",
    "\\end{align}\n",
    "\n",
    "对上面的算法中 j=1,2,...,n 时的更新式子进行调整可得： \n",
    "${{\\theta }_{j}}:={{\\theta }_{j}}(1-a\\frac{\\lambda }{m})-a\\frac{1}{m}\\sum\\limits_{i=1}^{m}{({{h}_{\\theta }}\\left( {{x}^{(i)}} \\right)-{{y}^{(i)}})x_{j}^{(i)}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([8.47457627e-03, 1.87880932e-02, 7.77711864e-05, 5.03446395e-02,\n",
       "       1.15013308e-02, 3.76648474e-02, 1.83559872e-02, 7.32393391e-03,\n",
       "       8.19244468e-03, 2.34764889e-02, 3.93486234e-02, 2.23923907e-03,\n",
       "       1.28600503e-02, 3.09593720e-03, 3.93028171e-02, 1.99707467e-02,\n",
       "       4.32983232e-03, 3.38643902e-03, 5.83822078e-03, 4.47629067e-03,\n",
       "       3.10079849e-02, 3.10312442e-02, 1.09740238e-03, 6.31570797e-03,\n",
       "       4.08503006e-04, 7.26504316e-03, 1.37646175e-03, 3.87936363e-02])"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def gradientReg(theta, X, y, l=1):\n",
    "    reg = (1 / len(X)) * theta\n",
    "    reg[0] = 0  \n",
    "    return gradient(theta, X, y) + reg\n",
    "\n",
    "gradientReg(theta, X, y, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 学习参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 1.02252845,  0.56283947,  1.13465378, -1.78530023, -0.66539149,\n",
       "        -1.01863396,  0.13957   , -0.29358944, -0.30102267, -0.08324513,\n",
       "        -1.27206004, -0.06137383, -0.53996526, -0.17881809, -0.9419886 ,\n",
       "        -0.14054855, -0.17736663, -0.0769737 , -0.22918951, -0.21349652,\n",
       "        -0.37205413, -0.86417673,  0.00890083, -0.26795962, -0.00362248,\n",
       "        -0.28315235, -0.07321588, -0.75992674]),\n",
       " 57,\n",
       " 4)"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result2 = opt.fmin_tnc(func=costReg, x0=theta, fprime=gradientReg, args=(X, y, 2))\n",
    "result2\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 验证正则化逻辑回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8050847457627118"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_theta = result2[0]\n",
    "predictions = predict(final_theta, X)\n",
    "correct = [1 if a==b else 0 for (a, b) in zip(predictions, y)]\n",
    "accuracy = sum(correct) / len(correct)\n",
    "accuracy\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "或者用skearn中的方法来评估结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.85      0.75      0.80        60\n",
      "           1       0.77      0.86      0.81        58\n",
      "\n",
      "    accuracy                           0.81       118\n",
      "   macro avg       0.81      0.81      0.80       118\n",
      "weighted avg       0.81      0.81      0.80       118\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(classification_report(y, predictions))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 决策边界"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-0.8, 1.2)"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(-1, 1.5, 250)\n",
    "xx, yy = np.meshgrid(x, x)\n",
    "\n",
    "z = feature_mapping(xx.ravel(), yy.ravel(), 6).values\n",
    "z = z @ final_theta\n",
    "z = z.reshape(xx.shape)\n",
    "\n",
    "plot_data()\n",
    "plt.contour(xx, yy, z, 0)\n",
    "plt.ylim(-.8, 1.2)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
